home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / src / binutils.252 / binutils / arsup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-16  |  8.5 KB  |  456 lines

  1. /* arsup.c - Archive support for MRI compatibility
  2.    Copyright (C) 1992 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU Binutils.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20.  
  21. /* Contributed by Steve Chamberlain
  22.              sac@cygnus.com
  23.  
  24. This file looks after requests from arparse.y, to provide the MRI
  25. style librarian command syntax + 1 word LIST
  26.  
  27. */
  28.  
  29. #include "bfd.h"
  30. #include "arsup.h"
  31. #include "libiberty.h"
  32. #include <sysdep.h>
  33. #include "bucomm.h"
  34.  
  35. static void map_over_list
  36.   PARAMS ((bfd *, void (*function) (bfd *, bfd *), struct list *));
  37. static void ar_directory_doer PARAMS ((bfd *, bfd *));
  38. static void ar_addlib_doer PARAMS ((bfd *, bfd *));
  39.  
  40. extern int verbose;
  41.  
  42. extern char *strdup();
  43.  
  44. static void
  45. map_over_list (arch, function, list)
  46.      bfd *arch;
  47.      void (*function) PARAMS ((bfd *, bfd *));
  48.      struct list *list;
  49. {
  50.   bfd            *head;
  51.  
  52.   if (list == 0) {
  53.     for (head = arch->next; head; head = head->next){
  54.       function (head, (bfd *) NULL);
  55.     }
  56.   }
  57.   else {
  58.     /*
  59.       This may appear to be a baroque way of accomplishing what we want.
  60.       however we have to iterate over the filenames in order to notice where
  61.       a filename is requested but does not exist in the archive.  Ditto
  62.       mapping over each file each time -- we want to hack multiple
  63.       references.
  64.       */
  65.     struct list *ptr = list;
  66.  
  67.     for (ptr = list; ptr; ptr=ptr->next)
  68.     {
  69.       boolean         found = false;
  70.       bfd *prev = arch;
  71.       for (head = arch->next; head; head = head->next) 
  72.       {
  73.     if ((head->filename != NULL) &&
  74.         (!strcmp(ptr->name, head->filename))) 
  75.     {
  76.       found = true;
  77.       function(head, prev);
  78.  
  79.     }
  80.     prev = head;
  81.       }
  82.       if (!found)
  83.        fprintf(stderr, "No entry %s in archive.\n", ptr->name);
  84.     }
  85.   }
  86. }
  87.  
  88.  
  89. FILE *outfile;
  90.  
  91. /*ARGSUSED*/
  92. static void
  93. ar_directory_doer (abfd, ignore)
  94.      bfd *abfd;
  95.      bfd *ignore;
  96. {
  97.     print_arelt_descr(outfile, abfd, verbose);
  98. }
  99.  
  100. void
  101. ar_directory (ar_name, list, output)
  102.      char *ar_name;
  103.      struct list *list;
  104.      char *output;
  105. {
  106.   bfd *arch;
  107.  
  108.   arch = open_inarch (ar_name);
  109.   if (output)
  110.     {
  111.       outfile = fopen(output,"w");
  112.       if (outfile == 0)
  113.     {
  114.       outfile = stdout;
  115.       fprintf (stderr,"Can't open file %s\n", output);
  116.       output = 0;
  117.     }
  118.     }
  119.   else 
  120.     outfile = stdout;
  121.  
  122.   map_over_list (arch, ar_directory_doer, list);
  123.  
  124.   bfd_close (arch);
  125.  
  126.   if (output)
  127.    fclose (outfile);
  128. }
  129.  
  130. void
  131. DEFUN_VOID(prompt)
  132. {
  133.   extern int interactive;
  134.   if (interactive) 
  135.   {
  136.     printf("AR >");
  137.     fflush(stdout); 
  138.   }
  139. }
  140.  
  141. void
  142. maybequit ()
  143. {
  144.   if (! interactive) 
  145.     xexit (9);
  146. }
  147.  
  148.  
  149. bfd *obfd;
  150. char *real_name ; 
  151. void
  152. DEFUN(ar_open,(name, t),
  153.       char *name AND
  154.       int t)
  155.  
  156. {
  157.   char *tname = malloc(strlen(name)+10);
  158.   real_name = name;
  159.   sprintf(tname, "%s-tmp", name);
  160.   obfd = bfd_openw(tname, NULL);
  161.  
  162.   if (!obfd) {
  163.     fprintf(stderr,"%s: Can't open output archive %s\n", program_name,
  164.         tname);
  165.  
  166.     maybequit();
  167.   }
  168.   else {
  169.     if (!t) {
  170.       bfd **ptr;
  171.       bfd *element;
  172.       bfd *ibfd;
  173.       ibfd = bfd_openr(name, NULL);
  174.       if (!ibfd) {
  175.     fprintf(stderr,"%s: Can't open input archive %s\n",
  176.         program_name, name);
  177.     maybequit();
  178.     return;
  179.       }
  180.       if (bfd_check_format(ibfd, bfd_archive) != true) {
  181.     fprintf(stderr,"%s: file %s is not an archive\n", program_name,
  182.         name);
  183.     maybequit();
  184.     return;
  185.       }
  186.       ptr = &(obfd->archive_head);
  187.       element = bfd_openr_next_archived_file(ibfd, NULL);
  188.  
  189.       while (element) {
  190.     *ptr = element;
  191.     ptr = &element->next;
  192.     element = bfd_openr_next_archived_file(ibfd, element);
  193.       }
  194.     }
  195.  
  196.     bfd_set_format(obfd, bfd_archive);
  197.  
  198.     obfd->has_armap = 1;
  199.   }
  200. }
  201.  
  202.  
  203. static void
  204. ar_addlib_doer (abfd, prev)
  205.      bfd *abfd;
  206.      bfd *prev;
  207. {
  208.   /* Add this module to the output bfd */
  209.   
  210.   prev->next = abfd->next;
  211.   abfd->next = obfd->archive_head;
  212.   obfd->archive_head = abfd;
  213. }
  214.  
  215. void
  216. ar_addlib (name, list)
  217.      char *name;
  218.      struct list *list;
  219. {
  220.   if (obfd == NULL)
  221.     {
  222.       fprintf (stderr, "%s: no output archive specified yet\n", program_name);
  223.       maybequit ();
  224.     }
  225.   else
  226.     {
  227.       bfd *arch;
  228.  
  229.       arch = open_inarch (name);
  230.       if (arch != NULL)
  231.     map_over_list (arch, ar_addlib_doer, list);
  232.  
  233.       /* Don't close the bfd, since it will make the elements disasppear */
  234.     }
  235. }
  236.  
  237. void
  238. DEFUN(ar_addmod, (list),
  239.       struct list *list)
  240. {
  241.   if (!obfd) {
  242.     fprintf(stderr, "%s: no open output archive\n", program_name);
  243.     maybequit();
  244.   }
  245.   else 
  246.   {
  247.     while (list) {
  248.       bfd *abfd = bfd_openr(list->name, NULL);
  249.       if (!abfd)  {
  250.     fprintf(stderr,"%s: can't open file %s\n", program_name,
  251.         list->name);
  252.     maybequit();
  253.       }
  254.       else {
  255.     abfd->next = obfd->archive_head;
  256.     obfd->archive_head = abfd;
  257.       }
  258.       list = list->next;
  259.     }
  260.   }
  261. }
  262.  
  263.  
  264.  
  265. void
  266. DEFUN_VOID(ar_clear)
  267. {
  268. if (obfd) 
  269.  obfd->archive_head = 0;
  270. }
  271.  
  272. void
  273. DEFUN(ar_delete, (list),
  274.       struct list *list)
  275. {
  276.   if (!obfd) {
  277.     fprintf(stderr, "%s: no open output archive\n", program_name);
  278.     maybequit();
  279.   }
  280.   else 
  281.   {
  282.     while (list) {
  283.       /* Find this name in the archive */
  284.       bfd *member = obfd->archive_head;
  285.       bfd **prev = &(obfd->archive_head);
  286.       int found = 0;
  287.       while (member) {
  288.     if (strcmp(member->filename, list->name) == 0) {
  289.       *prev = member->next;
  290.       found = 1;
  291.     }
  292.     else {
  293.       prev = &(member->next);
  294.     }
  295.       member = member->next;
  296.       }
  297.       if (!found)  {
  298.     fprintf(stderr,"%s: can't find module file %s\n", program_name,
  299.         list->name);
  300.     maybequit();
  301.       }
  302.       list = list->next;
  303.     }
  304.   }
  305. }
  306.  
  307.  
  308. void
  309. DEFUN_VOID(ar_save)
  310. {
  311.  
  312.   if (!obfd) {
  313.     fprintf(stderr, "%s: no open output archive\n", program_name);
  314.     maybequit();
  315.   }
  316.   else {
  317.     char *ofilename = strdup(bfd_get_filename (obfd));
  318.     bfd_close(obfd);
  319.     
  320.     unlink(real_name);
  321.     link(ofilename, real_name);
  322.     unlink(ofilename);
  323.     obfd = 0;
  324.     free(ofilename);
  325.   }
  326. }
  327.  
  328.  
  329.  
  330. void
  331. DEFUN(ar_replace, (list),
  332.       struct list *list)
  333. {
  334.   if (!obfd) {
  335.     fprintf(stderr, "%s: no open output archive\n", program_name);
  336.     maybequit();
  337.   }
  338.   else 
  339.   {
  340.     while (list) {
  341.       /* Find this name in the archive */
  342.       bfd *member = obfd->archive_head;
  343.       bfd **prev = &(obfd->archive_head);
  344.       int found = 0;
  345.       while (member) 
  346.       {
  347.     if (strcmp(member->filename, list->name) == 0) 
  348.     {
  349.       /* Found the one to replace */
  350.       bfd *abfd = bfd_openr(list->name, 0);
  351.       if (!abfd) 
  352.       {
  353.         fprintf(stderr, "%s: can't open file %s\n", program_name, list->name);
  354.         maybequit();
  355.       }
  356.       else {
  357.         *prev = abfd;
  358.         abfd->next = member->next;
  359.         found = 1;
  360.       }
  361.     }
  362.     else {
  363.       prev = &(member->next);
  364.     }
  365.     member = member->next;
  366.       }
  367.       if (!found)  {
  368.     bfd *abfd = bfd_openr(list->name, 0);
  369.     fprintf(stderr,"%s: can't find module file %s\n", program_name,
  370.         list->name);
  371.     if (!abfd) 
  372.     {
  373.       fprintf(stderr, "%s: can't open file %s\n", program_name, list->name);
  374.       maybequit();
  375.     }
  376.     else 
  377.     {
  378.       *prev = abfd;
  379.     }
  380.       }
  381.  
  382.     list = list->next;
  383.     }
  384.   }
  385. }
  386.  
  387. /* And I added this one */
  388. void
  389. DEFUN_VOID(ar_list)
  390. {
  391.   if (!obfd) 
  392.   {
  393.     fprintf(stderr, "%s: no open output archive\n", program_name);
  394.     maybequit();
  395.   }
  396.   else {
  397.     bfd *abfd;
  398.     outfile = stdout;
  399.     verbose =1 ;
  400.     printf("Current open archive is %s\n", bfd_get_filename (obfd));
  401.     for (abfd = obfd->archive_head;
  402.      abfd != (bfd *)NULL;
  403.      abfd = abfd->next) 
  404.     {
  405.       ar_directory_doer (abfd, (bfd *) NULL);
  406.     }
  407.   }
  408. }
  409.  
  410.  
  411. void 
  412. DEFUN_VOID(ar_end)
  413. {
  414.   if (obfd)
  415.   {
  416.     fclose((FILE *)(obfd->iostream));
  417.     unlink(bfd_get_filename (obfd));
  418.   }
  419. }
  420. void
  421. DEFUN(ar_extract,(list),
  422.       struct list *list)
  423. {
  424.   if (!obfd) 
  425.   {
  426.  
  427.     fprintf(stderr, "%s: no open  archive\n", program_name);
  428.     maybequit();
  429.   }
  430.   else 
  431.   {
  432.     while (list) {
  433.       /* Find this name in the archive */
  434.       bfd *member = obfd->archive_head;
  435.       int found = 0;
  436.       while (member && !found) 
  437.       {
  438.     if (strcmp(member->filename, list->name) == 0) 
  439.     {
  440.       extract_file(member);
  441.       found = 1;
  442.       }
  443.  
  444.     member = member->next;
  445.       }
  446.       if (!found)  {
  447.     bfd_openr(list->name, 0);
  448.     fprintf(stderr,"%s: can't find module file %s\n", program_name,
  449.         list->name);
  450.  
  451.       }
  452.       list = list->next;
  453.     }
  454.   }
  455. }
  456.